<template>
  <view class="notes-container">
    <!-- 顶部栏 -->
    <view class="header">
      <text class="header-title">笔记</text>
      <view class="header-actions">
        <view class="action-btn" @tap="showSearch">
          <text class="action-icon">🔍</text>
        </view>
        <view class="action-btn" @tap="showNotesMenu">
          <text class="action-icon">•••</text>
        </view>
      </view>
    </view>

    <!-- 搜索栏 -->
    <view class="search-bar" v-if="showSearchBar">
      <view class="search-input">
        <text class="search-icon">🔍</text>
        <input
          type="text"
          placeholder="搜索笔记"
          placeholder-style="color: #999"
          v-model="searchKeyword"
          @input="searchNotes"
        />
        <view class="clear-btn" @tap="clearSearch">
          <text class="clear-icon">✕</text>
        </view>
      </view>
    </view>

    <!-- 分类标签 -->
    <view class="category-tabs" v-if="!showSearchBar">
      <scroll-view scroll-x="true" class="tabs-scroll">
        <view
          class="tab-item"
          :class="{ active: selectedCategory === 'all' }"
          @tap="selectCategory('all')"
        >
          <text class="tab-text">全部</text>
        </view>
        <view
          class="tab-item"
          :class="{ active: selectedCategory === 'work' }"
          @tap="selectCategory('work')"
        >
          <text class="tab-text">工作</text>
        </view>
        <view
          class="tab-item"
          :class="{ active: selectedCategory === 'study' }"
          @tap="selectCategory('study')"
        >
          <text class="tab-text">学习</text>
        </view>
        <view
          class="tab-item"
          :class="{ active: selectedCategory === 'life' }"
          @tap="selectCategory('life')"
        >
          <text class="tab-text">生活</text>
        </view>
        <view
          class="tab-item"
          :class="{ active: selectedCategory === 'idea' }"
          @tap="selectCategory('idea')"
        >
          <text class="tab-text">创意</text>
        </view>
      </scroll-view>
    </view>

    <!-- 笔记列表 -->
    <view class="notes-list">
      <view v-if="filteredNotes.length === 0" class="empty-notes">
        <text class="empty-icon">📝</text>
        <text class="empty-text">暂无备忘录</text>
        <text class="empty-hint">点击下方按钮添加新笔记</text>
      </view>

      <view v-else>
        <view
          v-for="(note, index) in filteredNotes"
          :key="index"
          class="note-item"
          @tap="openNoteDetail(note)"
        >
          <view class="note-header">
            <text class="note-title">{{ note.title }}</text>
            <text class="note-date">{{ note.date }}</text>
          </view>
          <text class="note-content">{{ note.content }}</text>
          <view class="note-footer">
            <text class="note-category" :class="note.category">{{
              getCategoryName(note.category)
            }}</text>
            <view class="note-actions">
              <view class="action-btn small" @tap.stop="togglePin(note)">
                <text class="action-icon small">{{
                  note.pinned ? "📌" : "📍"
                }}</text>
              </view>
              <view
                class="action-btn small"
                @tap.stop="deleteNote(index, note)"
              >
                <text class="action-icon small">🗑️</text>
              </view>
            </view>
          </view>
        </view>
      </view>
    </view>

    <!-- 浮动按钮 -->
    <view class="floating-btn" @tap="addNewNote">
      <text class="btn-icon">+</text>
    </view>

    <!-- 底部导航 -->
    <view class="footer-nav">
      <view class="nav-item" @tap="openIndex">
        <text class="nav-icon">🏠</text>
        <text class="nav-text">首页</text>
      </view>
      <view class="nav-item" @tap="openSchedule">
        <text class="nav-icon">📅</text>
        <text class="nav-text">日程</text>
      </view>
      <view class="nav-item active">
        <text class="nav-icon">📝</text>
        <text class="nav-text">笔记</text>
      </view>
      <view class="nav-item" @tap="navigateToProfile">
        <text class="nav-icon">👤</text>
        <text class="nav-text">我的</text>
      </view>
    </view>
  </view>
</template>

<script>
export default {
  data() {
    return {
      showSearchBar: false,
      searchKeyword: "",
      selectedCategory: "all",
      notes: [
        {
          id: 11,
          title: "关于作者",
          content:
            "作者信息：\nCSDN用户名：孜然卷K\n个人成就：\n- 获得2701次点赞\n- 内容获得283次评论\n- 获得2524次收藏\n- 代码获得3,684次分享\n- 博客总访问量：195,608\n- 原创文章：67篇\n- 博客总排名：8,703名",
          date: "今天 16:20",
          category: "idea",
          pinned: true,
        },
        {
          id: 1,
          title: "小程序开发要点",
          content:
            "1. 登录授权流程\n2. 权限请求策略\n3. 组件化开发方案\n4. 数据存储管理\n5. 性能优化技巧",
          date: "今天 10:30",
          category: "work",
          pinned: true,
        },
        {
          id: 2,
          title: "产品需求文档解读",
          content:
            "主要功能点：\n- 用户认证系统\n- 数据可视化展示\n- 移动端适配优化\n- 第三方服务集成",
          date: "今天 09:15",
          category: "work",
          pinned: false,
        },
        {
          id: 4,
          title: "周末购物清单",
          content: "1. 蔬菜水果\n2. 日用品\n3. 书籍\n4. 运动装备",
          date: "昨天 14:20",
          category: "life",
          pinned: false,
        },

        {
          id: 15,
          title: "Babel 的编译过程",
          content:
            "Babel 是⼀个 JavaScript 编译器，是⼀个⼯具链，主要⽤于将采⽤ ECMAScript 2015+ 语法编写的代码转换为向后兼容的 JavaScript 语法，以便能够运⾏在当前和旧版本的浏览器或其他环境中。\nBabel 本质上就是在操作 AST 来完成代码的转译。AST是抽象语法树（Abstract Syntax Tree, AST）\n\nBabel 的功能很纯粹，它只是⼀个编译器。⼤多数编译器的⼯作过程可以分为三部分：\n1. 解析（Parse）：将源代码转换成更加抽象的表⽰⽅法（例如抽象语法树）。包括词法分析和语法分析。词法分析主要把字符流源代码（Char Stream）转换成令牌流（Token Stream），语法分析主要是将令牌流转换成抽象语法树（Abstract Syntax Tree，AST）。\n2. 转换（Transform）：通过 Babel 的插件能⼒，对（抽象语法树）做⼀些特殊处理，将⾼版本语法的 AST 转换成⽀持低版本语法的 AST。让它符合编译器的期望，当然在此过程中也可以对 AST 的 Node 节点进⾏优化操作，⽐如添加、更新以及移除节点等。\n3. ⽣成（Generate）：将 AST 转换成字符串形式的低版本代码，同时也能创建 Source Map 映射。\n\n经过这三个阶段，代码就被 Babel 转译成功了。\n\n如果想要了解更多，可以阅读和尝试：\n• 分析 AST：ASTexplorer.net\n• AST 规范：github.com/estree/estr",
          date: "今天 18:00",
          category: "study",
          pinned: false,
        },
        {
          id: 16,
          title: "项⽬优化",
          content:
            "移除⽣产环境的控制台打印。⽅案很多，esling+pre-commit、使⽤插件⾃动去除，插件包括babelplugin-transform-remove-console、uglifyjs-webpack-plugin、terser-webpack-plugin。最后选择了terser-webpack-plugin，脚⼿架vue-cli⽤这个插件来开启缓存和多线程打包，⽆需安装额外的插件，仅需在configureWebpack中设置terser插件的drop_console为true即可。最好还是养成良好的代码习惯，在开发基本完成后去掉⽆⽤的console，vscode中的turbo console就蛮好的。\n\n第三⽅库的按需加载。echarts，官⽅⽂档⾥是使⽤配置⽂件指定使⽤的模块，另⼀种使⽤babelplugin-equire实现按需加载。element-ui使⽤babel-plugin-component实现按需引⼊。\n\n前后端数据交换⽅⾯，推动项⽬组使⽤蓝湖、接⼝⽂档，与后端同学协商，规范后台数据返回。\n\n雅⻁军规提到的，避免css表达式、滤镜，较少DOM操作，优化图⽚、精灵图，避免图⽚空链接等。\n\n性能问题：⻚⾯加载性能、动画性能、操作性能。Performance API，记录性能数据。\n\nwinter重学前端优化技术⽅案：\n缓存：客⼾端控制的强缓存策略。\n降低请求成本：DNS 由客⼾端控制，隔⼀段时间主动请求获取域名IP，不⾛系统DNS。TCP/TLS连接复⽤，服务器升级到HTTP2，尽量合并域名。\n减少请求数：JS、CSS打包到HTML。JS控制图⽚异步加载、懒加载。⼩型图⽚使⽤data-uri。\n较少传输体积：尽量使⽤SVG\gradient代替图⽚。根据机型和⽹络状况控制图⽚清晰度。对低清晰度图⽚使⽤锐化来提升体验。设计上避免⼤型背景图。\n使⽤CDN加速，内容分发⽹络，是建⽴再承载⽹基础上的虚拟分布式⽹络，能够将源站内容缓存到全国或全球的节点服务器上。⽤⼾就近获取内容，提⾼了资源的访问速度，分担源站压⼒。",
          date: "今天 18:05",
          category: "study",
          pinned: false,
        },
        {
          id: 17,
          title: "CSS 选择器及优先级",
          content:
            '选择器：\n• id选择器(#myid)\n• 类选择器(.myclass)\n• 属性选择器(a[rel="external"])\n• 伪类选择器(a:hover, li:nth-child)\n• 标签选择器(div, h1,p)\n• 相邻选择器（h1 + p）\n• ⼦选择器(ul > li)\n• 后代选择器(li a)\n• 通配符选择器(*)\n优先级：\n• !important\n• 内联样式（1000）\n• ID选择器（0100）\n• 类选择器/属性选择器/伪类选择器（0010）\n• 元素选择器/伪元素选择器（0001）\n• 关系选择器/通配符选择器（0000）\n\n带!important 标记的样式属性优先级最⾼；样式表的来源相同时：!important > ⾏内样式>ID选择器 > 类选择器 > 标签 > 通配符 > 继承 > 浏览器默认属性。',
          date: "今天 18:10",
          category: "study",
          pinned: false,
        },
        {
          id: 12,
          title: "原型 && 原型链",
          content:
            "原型关系：\n• 每个 class都有显⽰原型 prototype\n• 每个实例都有隐式原型 _ proto_\n• 实例的_ proto_指向对应 class 的 prototype\n原型: 在 JS 中，每当定义⼀个对象（函数也是对象）时，对象中都会包含⼀些预定义的属性。其中每个 函数对象 都有⼀个 prototype 属性，这个属性指向函数的 原型对象 。\n原型链：函数的原型链对象constructor默认指向函数本⾝，原型对象除了有原型属性外，为了实现继承，还有⼀个原型链指针__proto__,该指针是指向上⼀层的原型对象，⽽上⼀层的原型对象的结构依然类似。因此可以利⽤__proto__⼀直指向Object的原型对象上，⽽Object原型对象用Object.prototype.__ proto__ = null表⽰原型链顶端。如此形成了js的原型链继承。同时所有的js对象都有Object的基本防范\n特点: JavaScript 对象是通过引⽤来传递的，我们创建的每个新对象实体中并没有⼀份属于⾃⼰的原型副本。当我们修改原型时，与之相关的对象也会继承这⼀改变。",
          date: "今天 17:30",
          category: "study",
          pinned: false,
        },
        {
          id: 13,
          title: "setTimeout、Promise、Async/Await 的区别",
          content:
            "1. setTimeout\nsettimeout的回调函数放到宏任务队列⾥，等到执⾏栈清空以后执⾏。\n\n2. Promise\nPromise本⾝是同步的⽴即执⾏函数，当在executor中执⾏resolve或者reject的时候, 此时是异步操作，会先执⾏then/catch等，当主栈完成后，才会去调⽤resolve/reject中存放的⽅法执⾏。",
          date: "今天 17:35",
          category: "study",
          pinned: false,
        },
        {
          id: 14,
          title: "Git 常⽤命令",
          content:
            "查看分⽀：git branch\n创建分⽀：git branch\n切换分⽀：git checkout\n创建+切换分⽀：git checkout -b\n合并某分⽀到当前分⽀：git merge\n删除分⽀：git branch -d",
          date: "今天 17:40",
          category: "study",
          pinned: false,
        },
        {
          id: 18,
          title: "聊聊react中class组件和函数组件的区别",
          content:
            '类组件是使⽤ES6 的 class 来定义的组件。函数组件是接收⼀个单⼀的 props 对象并返回⼀个React元素。\n\n关于React的两套API（类（class）API 和基于函数的钩⼦（hooks） API）。官⽅推荐使⽤钩⼦（函数），⽽不是类。因为钩⼦更简洁，代码量少，⽤起来⽐较"轻"，⽽类⽐较"重"。⽽且，钩⼦是函数，更符合 React 函数式的本质。\n\n函数⼀般来说，只应该做⼀件事，就是返回⼀个值。如果你有多个操作，每个操作应该写成⼀个单独的函数。⽽且，数据的状态应该与操作⽅法分离。根据函数这种理念，React 的函数组件只应该做⼀件事情：返回组件的 HTML 代码，⽽没有其他的功能。函数的返回结果只依赖于它的参数。不改变函数体外部数据、函数执⾏过程⾥⾯没有副作⽤。\n\n类（class）是数据和逻辑的封装。也就是说，组件的状态和操作⽅法是封装在⼀起的。如果选择了类的写法，就应该把相关的数据和操作，都写在同⼀个 class ⾥⾯。\n\n类组件的缺点:\n⼤型组件很难拆分和重构，也很难测试。\n业务逻辑分散在组件的各个⽅法之中，导致重复逻辑或关联逻辑。\n组件类引⼊了复杂的编程模式，⽐如 render props 和⾼阶组件。\n难以理解的 class，理解 JavaScript 中 this 的⼯作⽅式。\n\n区别：\n函数组件的性能⽐类组件的性能要⾼，因为类组件使⽤的时候要实例化，⽽函数组件直接执⾏函数取返回结果即可。\n\n1.状态的有⽆\nhooks出现之前，函数组件没有实例，没有⽣命周期，没有state，没有this，所以我们称函数组件为⽆状态组件。hooks出现之前，react中的函数组件通常只考虑负责UI的渲染，没有⾃⾝的状态没有业务逻辑代码，是⼀个纯函数。它的输出只由参数props决定，不受其他任何因素影响。\n\n2.调⽤⽅式的不同\n函数组件重新渲染，将重新调⽤组件⽅法返回新的react元素。类组件重新渲染将new⼀个新的组件实例，然后调⽤render类⽅法返回react元素，这也说明为什么类组件中this是可变的。\n\n3.因为调⽤⽅式不同，在函数组件使⽤中会出现问题\n在操作中改变状态值，类组件可以获取最新的状态值，⽽函数组件则会按照顺序返回状态值。',
          date: "今天 18:15",
          category: "study",
          pinned: false,
        },
        {
          id: 19,
          title: "React Hooks（钩⼦的作⽤）",
          content:
            "Hook 是 React 16.8 的新增特性。它可以让你在不编写 class 的情况下使⽤ state 以及其他的 React 特性。\n\nReact Hooks的⼏个常⽤钩⼦:\n1. useState() //状态钩⼦\n2. useContext() //共享状态钩⼦\n3. useReducer() //action 钩⼦\n4. useEffect() //副作⽤钩⼦\n\n还有⼏个不常⻅的：\n• 1.useCallback 记忆函数 ⼀般把函数式组件理解为class组件render函数的语法糖，所以每次重新渲染的时候，函数式组件内部所有的代码都会重新执⾏⼀遍。⽽有了 useCallback 就不⼀样了，你可以通过 useCallback 获得⼀个记忆后的函数。\n\n第⼆个参数传⼊⼀个数组，数组中的每⼀项⼀旦值或者引⽤发⽣改变，useCallback 就会重新返回⼀个新的记忆函数提供给后⾯进⾏渲染。\n\n• 2.useMemo 记忆组件 useCallback 的功能完全可以由 useMemo 所取代，如果你想通过使⽤useMemo 返回⼀个记忆函数也是完全可以的。唯⼀的区别是：useCallback 不会执⾏第⼀个参数函数，⽽是将它返回给你，⽽ useMemo 会执⾏第⼀个函数并且将函数执⾏结果返回给你。\n所以 useCallback 常⽤记忆事件函数，⽣成记忆后的事件函数并传递给⼦组件使⽤。⽽ useMemo更适合经过函数计算得到⼀个确定的值，⽐如记忆组件。\n\n• 3.useRef 保存引⽤值\nuseRef 跟 createRef 类似，都可以⽤来⽣成对 DOM 对象的引⽤。useRef 返回的值传递给组件或者 DOM 的 ref 属性，就可以通过 ref.current 值访问组件或真实的 DOM 节点，重点是组件也是可以访问到的，从⽽可以对 DOM 进⾏⼀些操作，⽐如监听事件等等。\n\n• 4.useImperativeHandle 穿透 Ref\n通过 useImperativeHandle ⽤于让⽗组件获取⼦组件内的索引\n\n• 5.useLayoutEffect 同步执⾏副作⽤\n⼤部分情况下，使⽤ useEffect 就可以帮我们处理组件的副作⽤，但是如果想要同步调⽤⼀些副作⽤，⽐如对 DOM 的操作，就需要使⽤ useLayoutEffect，useLayoutEffect 中的副作⽤会在 DOM更新之后同步执⾏。\n\nuseEffect和useLayoutEffect有什么区别：简单来说就是调⽤时机不同，useLayoutEffect和原来componentDidMount&componentDidUpdate⼀致，在react完成DOM更新后⻢上同步调⽤的代码，会阻塞⻚⾯渲染。⽽useEffect是会在整个⻚⾯渲染完才会调⽤的代码。官⽅建议优先使⽤useEffect。",
          date: "今天 18:20",
          category: "study",
          pinned: false,
        },
        {
          id: 20,
          title: "前端组件的多层渲染",
          content:
            '组件分层架构\n基础组件层:这⼀层包含最基本的 U 组件，如⽂本框、按钮、标签等。这些组件⽤于展⽰最基。础的数据。例如，在⼀个表单中，⽤⽂本框展⽰客户姓名，⽤标签展⽰客户的会员等级。\n组合组件层:将基础组件组合成更复杂的组件。⽐如，将⼀个⽂本框和⼀个按钮组合成⼀个搜。索组件，⽤于在客户列表中搜索特定客户。组合组件可以在低代码平台中通过简单的拖拽和配置来实现，如设置按钮的点击事件来触发⽂本框内容的搜索操作。\n业务组件层:根据业务逻辑构建组件，这些组件可能包含多个组合组件或者基础组件，并且具有特定的业务功能。例如，在⼀个销售管理系统中，有⼀个"销售订单详情"业务组件，它包含客户信息部分(由多个基础组件展⽰客户姓名、联系方式等)、订单商品列表部分(可能是⼀个表格组件，展⽰商品名称、数量、价格等)和订单操作部分(如确认订单、取消订单等按钮)。',
          date: "今天 18:30",
          category: "study",
          pinned: false,
        },
        {
          id: 21,
          title: "vite 预构建",
          content:
            "Vite 预构建的概念\nVite 的预构建(Pre-building)是其核⼼特性之⼀。它主要是在开发服务器启动时，对项⽬中的某些模块进⾏提前构建。这就好⽐是在⼀场演出开始前，先把舞台上复杂的道具和场景提前搭建好，这样在演出(开发过程)中能够更顺畅地进⾏。\n预构建的主要⽬的是为了提⾼开发服务器的启动速度和模块热更新(HMR)的性能。在 Vite 中，模块是以原⽣的 ES 模块(ESM)格式提供的，但是在实际项⽬中，很多第三⽅库是以CommonJs 格式发布的，或者包含⼤量的内部模块引⽤。预构建可以将这些⾮ ESM 格式的模块转换为 ESM 格式，并且将多个内部模块合并成⼀个模块，减少浏览器请求次数。",
          date: "今天 18:35",
          category: "study",
          pinned: false,
        },
        {
          id: 22,
          title: "服务流程规范",
          content:
            "热线： 收集用户信息（升级到一线前提用户信息无误）\n1、记录故障问题，并且收集主机序列号sn、单位、电话、姓名、地址\n2、初步故障排查\n3、记录工单并跟进至闭环。\n\n一线： 简单排查（升级到二线前提告知已哪些排查步骤，问题解决仍存在提供目前故障现象）\n1、收到工单第一时间联系用户\n2、进行简单的排查\n3、上门/线上收集信息，备件更换等\n\n二线： 确认排查（升级到三线前提收集日志，及故障现状，排查办法）\n1、根据现场反馈，进行判断是否需要研发接入\n2、定位问题，提供解决方案\n3、维护知识库的文档，确保配置信息准确性\n\n三线： 修复\n1、修复系统核心BUG\n2、主导硬件优化",
          date: "今天 18:40",
          category: "work",
          pinned: false,
        },
        {
          id: 23,
          title: "家常菜谱合集",
          content:
            "1. 江浙菜：绍兴酒糟毛豆\n材料：\n新鲜或冷冻毛豆 300克\n绍兴酒糟 3-4汤匙（带汁）\n盐 1茶匙\n八角 1颗（可选）\n桂皮 1小片（可选）\n清水 适量\n做法：\n毛豆洗净，用剪刀剪去两头（更易入味）。\n锅中加水、盐、八角、桂皮煮沸，放入毛豆煮8-10分钟至熟透。\n捞出毛豆，沥干水分，趁热放入干净容器中。\n加入酒糟和1-2汤匙煮毛豆的水，搅拌均匀，确保毛豆被酒糟汁浸没。\n冷却后盖上盖子，冰箱冷藏腌制4小时以上（隔夜更佳），即可食用。\n\n2. 江浙菜：糖醋小排（迷你版/配菜版）\n材料：\n猪小排 300克（切小块）\n料酒 1汤匙\n生抽 1汤匙\n老抽 半汤匙\n冰糖 20克\n香醋 2汤匙\n清水 适量\n姜片 2片\n花椒 几粒（可选）\n做法：\n小排冷水下锅，加料酒、姜片焯水，捞出洗净沥干。\n锅中放少许油，加入冰糖，小火炒至融化呈琥珀色（炒糖色）。\n倒入排骨快速翻炒上色。\n加入生抽、老抽、香醋、花椒，翻炒均匀。\n加入没过排骨的清水，大火煮开后转小火炖20-25分钟。\n开盖转大火收汁至浓稠发亮即可。作为配菜，可稍多留一点汤汁。\n\n3. 川菜：凉拌折耳根（鱼腥草）\n材料：\n新鲜折耳根（嫩茎） 200克\n大蒜 3瓣（切末）\n小米辣 1-2个（切圈，根据辣度调整）\n香葱 1根（切葱花）\n生抽 2汤匙\n香醋 1汤匙\n白糖 半茶匙\n盐 少许\n香油 1茶匙\n辣椒油 1-2汤匙（可选）\n做法：\n折耳根摘去老根，洗净，切成3-4厘米长的段，用盐水浸泡10分钟后捞出沥干（去涩味）。\n将折耳根放入碗中，加入蒜末、小米辣、葱花。\n加入生抽、香醋、白糖、盐、香油、辣椒油。\n充分拌匀，静置10分钟入味即可食用。\n\n4. 川菜：麻婆豆腐（配菜版）\n材料：\n嫩豆腐 1块（约350克）\n牛肉末 或 猪肉末 50克\n郫县豆瓣酱 1.5汤匙\n豆豉 1茶匙（切碎，可选但更地道）\n蒜末 1汤匙\n姜末 1茶匙\n花椒粉 1茶匙（分两次用）\n辣椒粉 半茶匙（可选）\n生抽 1汤匙\n糖 半茶匙\n清水 或 高汤 200ml\n水淀粉 适量（淀粉+水）\n葱花 少许\n做法：\n豆腐切小块，放入加盐的开水中浸泡5分钟，捞出沥干。\n热锅冷油，下肉末炒至变色，盛出备用。\n锅中再加点油，小火炒香豆瓣酱和豆豉，出红油后加入姜蒜末炒香。\n加入生抽、糖、辣椒粉、清水煮开。\n轻轻放入豆腐块和炒好的肉末，小火煮3-5分钟。\n淋入水淀粉勾芡2-3次（川菜\"推芡\"手法，汤汁浓稠包裹豆腐）。\n出锅前撒上一半花椒粉，装盘后再撒剩余花椒粉和葱花。\n\n5. 江浙菜：雪菜毛豆炒肉末\n材料：\n雪菜（雪里蕻咸菜） 100克（切碎，用清水泡10分钟去咸）\n毛豆仁 150克（新鲜或冷冻）\n猪肉末 100克\n姜末 1茶匙\n食用油 2汤匙\n糖 1茶匙\n料酒 1茶匙（可选）\n做法：\n泡过的雪菜挤干水分。毛豆仁焯水2-3分钟至熟，捞出沥干。\n热锅放油，下肉末炒至变色，烹入料酒（如果用）。\n加入姜末炒香，再加入雪菜碎翻炒出香味。\n倒入毛豆仁，翻炒均匀。\n加入糖调味（雪菜本身有咸味，通常无需再加盐），翻炒2-3分钟即可出锅。",
          date: "今天 18:45",
          category: "life",
          pinned: false,
        },
      ],
      filteredNotes: []
    };
  },
  onLoad() {
    this.filterNotes();
  },
  methods: {
    // 过滤笔记
    filterNotes() {
      let filtered = [...this.notes];

      // 按分类过滤
      if (this.selectedCategory !== "all") {
        filtered = filtered.filter(
          (note) => note.category === this.selectedCategory
        );
      }

      // 按搜索关键词过滤
      if (this.searchKeyword) {
        const keyword = this.searchKeyword.toLowerCase();
        filtered = filtered.filter(
          (note) =>
            note.title.toLowerCase().includes(keyword) ||
            note.content.toLowerCase().includes(keyword)
        );
      }

      // 按置顶和日期排序
      filtered.sort((a, b) => {
        if (a.pinned && !b.pinned) return -1;
        if (!a.pinned && b.pinned) return 1;
        // 这里简化处理，实际应该比较日期对象
        return 0;
      });

      this.filteredNotes = filtered;
    },

    // 显示搜索栏
    showSearch() {
      this.showSearchBar = true;
      // 自动聚焦搜索框
      setTimeout(() => {
        const input = uni.createSelectorQuery().select(".search-input input");
        input
          .fields({ node: true }, (res) => {
            if (res.node) {
              res.node.focus();
            }
          })
          .exec();
      }, 100);
    },

    // 隐藏搜索栏
    hideSearch() {
      this.showSearchBar = false;
      this.searchKeyword = "";
      this.filterNotes();
    },

    // 清除搜索
    clearSearch() {
      this.searchKeyword = "";
      this.filterNotes();
    },

    // 搜索笔记
    searchNotes() {
      this.filterNotes();
    },

    // 底部导航栏方法
    openIndex() {
      uni.redirectTo({ url: "/pages/demo/index" });
    },

    openSchedule() {
      uni.redirectTo({ url: "/pages/demo/schedule" });
    },

    navigateToProfile() {
      uni.redirectTo({ url: "/pages/demo/profile" });
    },

    // 选择分类
    selectCategory(category) {
      this.selectedCategory = category;
      this.filterNotes();
    },

    // 获取分类名称
    getCategoryName(category) {
      const categoryMap = {
        work: "工作",
        study: "学习",
        life: "生活",
        idea: "创意",
      };
      return categoryMap[category] || "其他";
    },

    // 打开笔记详情
    openNoteDetail(note) {
      uni.navigateTo({
        url: `/pages/demo/note-detail?id=${note.id}&title=${encodeURIComponent(
          note.title
        )}&content=${encodeURIComponent(note.content)}&category=${
          note.category
        }&date=${encodeURIComponent(note.date)}`,
      });
    },

    // 切换置顶状态
    togglePin(note) {
      note.pinned = !note.pinned;
      this.filterNotes();

      uni.showToast({
        title: note.pinned ? "已置顶" : "取消置顶",
        icon: "none",
      });
    },

    // 删除笔记
    deleteNote(index, note) {
      uni.showModal({
        title: "确认删除",
        content: `确定要删除"${note.title}"吗？`,
        success: (res) => {
          if (res.confirm) {
            this.notes.splice(
              this.notes.findIndex((n) => n.id === note.id),
              1
            );
            this.filterNotes();

            uni.showToast({
              title: "删除成功",
            });
          }
        },
      });
    },

    // 添加新笔记
    addNewNote() {
      uni.navigateTo({
        url: "/pages/demo/add-note",
      });
    },

    // 显示笔记菜单
    showNotesMenu() {
      uni.showActionSheet({
        itemList: ["新建笔记", "新建文件夹", "设置"],
        success: (res) => {
          if (res.tapIndex === 0) {
            this.addNewNote();
          } else if (res.tapIndex === 1) {
            this.createNewFolder();
          } else if (res.tapIndex === 2) {
            this.navigateToSettings();
          }
        },
      });
    },

    // 创建新文件夹
    createNewFolder() {
      uni.showModal({
        title: "创建文件夹",
        content: "请输入文件夹名称",
        editable: true,
        success: (res) => {
          if (res.confirm && res.content) {
            uni.showToast({
              title: `文件夹"${res.content}"创建成功`,
              icon: "none",
            });
          }
        },
      });
    },

    // 导航到设置
    navigateToSettings() {
      uni.navigateTo({
        url: "/pages/demo/settings",
      });
    },
  },
};
</script>

<style scoped>
.notes-container {
  height: 100vh;
  background-color: #f8f9fc;
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  padding-bottom: 100rpx;
}

/* 顶部栏 */
.header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 30rpx 40rpx;
  background-color: #fff;
  box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.05);
}

.header-title {
  font-size: 36rpx;
  font-weight: 600;
  color: #333;
}

.header-actions {
  display: flex;
  align-items: center;
}

.action-btn {
  margin-left: 30rpx;
}

.action-icon {
  font-size: 32rpx;
  color: #333;
}

.action-icon.small {
  font-size: 28rpx;
}

/* 搜索栏 */
.search-bar {
  padding: 20rpx 30rpx;
  background-color: #fff;
  box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.05);
}

.search-input {
  display: flex;
  align-items: center;
  background-color: #f2f2f2;
  border-radius: 40rpx;
  padding: 15rpx 25rpx;
}

.search-icon {
  font-size: 28rpx;
  color: #999;
  margin-right: 15rpx;
}

.search-input input {
  flex: 1;
  font-size: 28rpx;
  color: #333;
  background: transparent;
}

.clear-btn {
  padding: 0 10rpx;
}

.clear-icon {
  font-size: 28rpx;
  color: #999;
}

/* 分类标签 */
.category-tabs {
  background-color: #fff;
  box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.05);
}

.tabs-scroll {
  white-space: nowrap;
  padding: 10rpx 0;
}

.tab-item {
  display: inline-block;
  padding: 15rpx 30rpx;
  margin: 0 10rpx;
  border-radius: 25rpx;
}

.tab-item.active {
  background-color: #667eea;
}

.tab-text {
  font-size: 28rpx;
  color: #333;
}

.tab-item.active .tab-text {
  color: #fff;
}

/* 笔记列表 */
.notes-list {
  padding: 20rpx;
}

.empty-notes {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 200rpx 0;
}

.empty-icon {
  font-size: 120rpx;
  margin-bottom: 30rpx;
}

.empty-text {
  font-size: 32rpx;
  color: #666;
  margin-bottom: 15rpx;
}

.empty-hint {
  font-size: 26rpx;
  color: #999;
}

.note-item {
  background-color: #fff;
  border-radius: 20rpx;
  padding: 30rpx;
  margin-bottom: 20rpx;
  box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.05);
}

.note-header {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  margin-bottom: 15rpx;
}

.note-title {
  font-size: 32rpx;
  font-weight: 600;
  color: #333;
  flex: 1;
  margin-right: 20rpx;
}

.note-date {
  font-size: 24rpx;
  color: #999;
  white-space: nowrap;
}

.note-content {
  font-size: 28rpx;
  color: #666;
  line-height: 1.6;
  margin-bottom: 20rpx;
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.note-footer {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.note-category {
  font-size: 24rpx;
  padding: 6rpx 16rpx;
  border-radius: 15rpx;
  background-color: #f2f2f2;
}

.note-category.work {
  background-color: #e3f2fd;
  color: #1976d2;
}

.note-category.study {
  background-color: #e8f5e9;
  color: #388e3c;
}

.note-category.life {
  background-color: #fff3e0;
  color: #f57c00;
}

.note-category.idea {
  background-color: #f3e5f5;
  color: #7b1fa2;
}

.note-actions {
  display: flex;
  align-items: center;
}

.action-btn.small {
  margin-left: 20rpx;
}

/* 浮动按钮 */
.floating-btn {
  position: fixed;
  right: 40rpx;
  bottom: 140rpx;
  width: 100rpx;
  height: 100rpx;
  background-color: #667eea;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.15);
}

.btn-icon {
  font-size: 48rpx;
  color: #fff;
  line-height: 1;
}

/* 为内容区域添加底部内边距，防止被导航栏遮挡 */
.notes-list {
  padding-bottom: 140rpx !important;
}

/* 底部导航样式 */
.footer-nav {
  display: flex;
  justify-content: space-around;
  align-items: center;
  height: 120rpx;
  background-color: #ffffff;
  box-shadow: 0 -2rpx 10rpx rgba(0, 0, 0, 0.05);
  border-top: 1rpx solid #eeeeee;
  /* 固定在底部并适配不同设备 */
  position: fixed;
  bottom: 0;
  left: 0;
  right: 0;
  z-index: 999;
}

.nav-item {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 10rpx 0;
  color: #999999;
}

.nav-item.active {
  color: #07c160;
}

.nav-icon {
  font-size: 40rpx;
  margin-bottom: 8rpx;
}

.nav-text {
  font-size: 24rpx;
}
</style>
